package com.ideaaedi.extspringcache.provider;


import com.ideaaedi.extspringcache.custom.ExtRedisCacheManagerCustomizer;
import com.ideaaedi.extspringcache.custom.ExtRedisSerializerCustomizer;
import com.ideaaedi.extspringcache.properties.ExtSpringCacheProperties;
import com.ideaaedi.extspringcache.redis.ExtRedisCacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * provider common逻辑抽取
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2023-05-31 13:30:25
 */
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public class CommonRedisProvider {
    
    @Autowired
    private ExtSpringCacheProperties extSpringCacheProperties;
    
    @Autowired(required = false)
    private CacheProperties cacheProperties;
    
    @Autowired(required = false)
    private ClassLoader classLoader;
    
    @Autowired(required = false)
    private ExtRedisSerializerCustomizer extRedisSerializerCustomizer;
    
    @Autowired(required = false)
    private ExtRedisCacheManagerCustomizer extRedisCacheManagerCustomizer;
    
    protected ExtRedisCacheManager getExtRedisCacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
        RedisSerializationContext.SerializationPair<String> keySerializer;
        RedisSerializationContext.SerializationPair<Object> valueSerializer;
        if (extRedisSerializerCustomizer != null) {
            keySerializer = extRedisSerializerCustomizer.keySerializer();
            Objects.requireNonNull(keySerializer, "keySerializer cannot be null.");
            valueSerializer = extRedisSerializerCustomizer.valueSerializer();
            Objects.requireNonNull(valueSerializer, "valueSerializer cannot be null.");
        } else {
            keySerializer = RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer(StandardCharsets.UTF_8));
            valueSerializer = RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader));
        }
        ExtRedisCacheManager extRedisCacheManager;
        if (extRedisCacheManagerCustomizer != null) {
            extRedisCacheManager = extRedisCacheManagerCustomizer.customBuild(redisTemplate, cacheProperties, classLoader);
            Objects.requireNonNull(extRedisCacheManager, "extRedisCacheManager cannot be null.");
        } else {
            ExtRedisCacheManager.ExtRedisCacheManagerBuilder builder = ExtRedisCacheManager.ExtRedisCacheManagerBuilder.builder(redisTemplate);
            builder.customSerializer(keySerializer, valueSerializer);
            if (extSpringCacheProperties.getRedis().isResponseSpringContext()) {
                builder.customCacheConfig(cacheProperties);
            }
            extRedisCacheManager = builder.build();
        }
        extRedisCacheManager.initializeCaches();
        return extRedisCacheManager;
    }
}
